# -*- coding: utf-8 -*-
from scrapy.spider import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from baike_avp.items import BaikeAvpItem


class ArticleSpider(CrawlSpider):
    """
    根据start_urls定义范围内所有的词条页面，及其子页面，抓取xpath抽取到的元素。
    一定要使用重载的parse_start_url作为回调函数，否则爬虫将无法爬取start_urls
    页面，只能爬取其子页面（根据rules抽取到的页面）。
    """

    name = 'avp'
    allowed_domains = ['baike.baidu.com']
    start_urls = ['http://baike.baidu.com/view/' + str(pageId) + '.htm' for pageId in xrange(0, 989599)]

    # For Debug
    # start_urls = ['http://baike.baidu.com/view/989591.htm']

    rules = (
        Rule(LinkExtractor(allow=(r'/subview/.*',)), follow=True, callback='parse_start_url'),
    )

    def parse_start_url(self, response):

        # 判断词条页面是否有InfoBox
        if response.xpath('//*[@id="baseInfoWrapDom"]'):
            item = BaikeAvpItem()

            # 第一个xpath提取词条主标题，第二个xpath提取当该词条是多义词时才有的副标题
            item['subject'] = response.xpath('//*[@id="sec-content0"]/h1/span[1]/text()').extract()\
                + response.xpath('//*[@id="sec-content0"]/h1/span[1]/span/text()').extract()
            avps = response.xpath('//*[@id="baseInfoWrapDom"]//div[@class="biItemInner"]')

            # 提取InfoBox中的Title和Content，Content中有可能部分或全部值是超链接，
            # 当前是先提取超链接，再提取文本，再将两者拼接起来（因此有可能破坏了原有顺序或意义）
            for index, avp in enumerate(avps):
                item['relation'] = avp.xpath('//*[@class="biTitle"]' + '[' + str(index+1) + ']' + '/text()').extract()
                item['guest'] = avp.xpath('//*[@class="biContent"]' + '[' + str(index+1) + ']' + '/a/text()').extract()\
                    + avp.xpath('//*[@class="biContent"]' + '[' + str(index+1) + ']' + '/text()').extract()
                yield item